home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / serverlib / disk / selectDisk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  7.3 KB  |  252 lines

  1. /*
  2.  *   $RCSfile: selectDisk.c,v $  
  3.  *   $Revision: 1.1.1.1 $  
  4.  *   $Date: 1996/05/04 21:55:40 $      
  5.  */ 
  6. /**********************************************************************
  7. * EXODUS Database Toolkit Software
  8. * Copyright (c) 1991 Computer Sciences Department, University of
  9. *                    Wisconsin -- Madison
  10. * All Rights Reserved.
  11. *
  12. * Permission to use, copy, modify and distribute this software and its
  13. * documentation is hereby granted, provided that both the copyright
  14. * notice and this permission notice appear in all copies of the
  15. * software, derivative works or modified versions, and any portions
  16. * thereof, and that both notices appear in supporting documentation.
  17. *
  18. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  19. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  20. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  21. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  22. *
  23. * The EXODUS Project Group requests users of this software to return 
  24. * any improvements or extensions that they make to:
  25. *
  26. *   EXODUS Project Group 
  27. *     c/o David J. DeWitt and Michael J. Carey
  28. *   Computer Sciences Department
  29. *   University of Wisconsin -- Madison
  30. *   Madison, WI 53706
  31. *
  32. *     or exodus@cs.wisc.edu
  33. *
  34. * In addition, the EXODUS Project Group requests that users grant the 
  35. * Computer Sciences Department rights to redistribute these changes.
  36. **********************************************************************/
  37. #include "mutex_compile.h"
  38.  
  39. #include "sysdefs.h"
  40. #include "ess.h"
  41. #include "checking.h"
  42. #include "trace.h"
  43. #include "error.h"
  44. #include "list.h"
  45. #include "tid.h"
  46. #include "io.h"
  47. #include "lock.h"
  48. #include "object.h"
  49. #include "msgdefs.h"
  50. #include "thread.h"
  51. #include "semaphore.h"
  52. #include "latch.h"
  53. #include "link.h"
  54. #include "host.h"
  55. #include "bitvec.h"
  56. #include "bf.h"
  57. #include "disk.h"
  58. #include "volume.h"
  59. #include "pool.h"
  60. #include "threadstate.h"
  61. #include "msgvector.h"
  62. #include "msg_funcs.h"
  63. #include "thread_funcs.h"
  64. #include "disk_funcs.h"
  65. #include "mr_extfuncs.h"
  66. #include "thread_globals.h"
  67. #include "msg_globals.h"
  68. #include "recover_globals.h"
  69. #include "io_globals.h"
  70. #include "sm_params.h"
  71. #include "queue_globals.h"
  72. #include "stat_globals.h"
  73. #include "queue_consist.h"
  74. #include "sm_params.h"
  75.  
  76. /*
  77.  * selectDisk() is a bit of a misnomer, since no select() system
  78.  * call is done.  This routine just checks all the disk
  79.  * queues to see if any are ready to deliver results to the 
  80.  * server process.  If not, the select() system call in loop()
  81.  * will wait to be kicked by the disk processes.  This
  82.  * routine simply allows the two processes to avoid some
  83.  * unnecessary socket activity.
  84.  */
  85.  
  86.  
  87. /*
  88.  * First priority:
  89.  *   If there are any completed requests, process them (don't return).
  90.  * 2nd priority:
  91.  *   If any threads are waiting to write to a disk and the
  92.  *   disk can now accommodate them, move the thread to the 
  93.  *   ready list (move only the first such thread for each disk).  
  94.  *   Return 1 if any threads found, 0 if not.
  95.  */
  96.  
  97.  int
  98. selectDisk ()
  99.  
  100. {
  101. #ifdef JUNK
  102.     static TIMEVAL        Poll = { 0,0 };
  103. #endif JUNK
  104.     static int             lastFromQChecked= 0,
  105.                         lastToQChecked= 0; 
  106.     register int         j,last, found=0, failed=0;
  107.     register QUEUEPAIR     *qp;
  108.     register VOLREC     *volRec;
  109.  
  110.     TRPRINT(TR_DISK, TR_LEVEL_3, 
  111.         ("select disk, lastTo %d, lastFrom %d",lastToQChecked,
  112.         lastFromQChecked));
  113.     
  114.     /*
  115.      * Replies->willBlock means that the consumer of the replies (server
  116.      * process) will do a select before it checks the queues again.
  117.      * When it's false, the server will check the queues before doing
  118.      * its next select.  It's not precise; it's slightly pessimistic,
  119.      * as you can see: we're about to check the queues right now.
  120.      * But that's ok, since being kicked unnecessarily by a disk process
  121.      * to get us out of a select is not an error; it's just an
  122.      * inefficiency.  We hope that 99% of the time, this semaphore
  123.      * will prevent unnecessary kicks.
  124.      */
  125.     Replies->willBlock = 1;
  126.     TRPRINT(TR_DISK|TR_DISKRW, TR_LEVEL_1, ("Server willBlock"));
  127.  
  128. checkAll:
  129.     TRPRINT(TR_DISK|TR_DISKRW, TR_LEVEL_1, ("checking fromDisk Qs"));
  130.     last = lastFromQChecked;
  131.     for(j=last+1, lastFromQChecked=j%NumVolumes; 
  132.             (disk_requests_out>0) && (j<=(last+NumVolumes));
  133.             lastFromQChecked = (++j)%NumVolumes) {
  134.  
  135.         TRPRINT(TR_DISK|TR_DISKRW, TR_LEVEL_1, 
  136.             ("checking fromDisk #%d", lastFromQChecked));
  137.         qp = diskQueue(lastFromQChecked);
  138.         volRec  = qp->volRec;
  139.         SM_ASSERT( LEVEL_1, (volRec != NULL) );
  140.         SM_ASSERT(LEVEL_1, (volRec->queues == qp));
  141.         if( volRec->diskrwPid == 0 )  /* not mounted */
  142.             continue;
  143.         TRPRINT(TR_DISK|TR_DISKRW, TR_LEVEL_1, 
  144.             ("checking from Q disk %d", lastFromQChecked));
  145.  
  146.         SM_ASSERT(LEVEL_3, (qp!=NULL));
  147.  
  148.         /* 
  149.          * we mustn't block here, so we only try once for the turn 
  150.          */
  151.         if(tryMutex(&(qp->fromDisk.mutex))) {
  152.             disk_replies_found++;
  153.             diskReceiveQ(qp, TRUE /* holding mutex */);
  154.             /* if we return, there wasn't anything to receive.
  155.              * and, btw, we gave up the mutex
  156.              */
  157.             disk_replies_found--;
  158.         } else {
  159.             failed++;
  160.         }
  161.     }
  162.     if(failed) {
  163.         /*
  164.          *  If we get here,  we didn't get any work from any of the
  165.          *  disk queues.  The reason is one of two: either
  166.          *   none of the disks had anything to give us, or
  167.          *   some disk process was using its queue so we failed
  168.          *   to get mutex on that queue with the tryMutex() call above.
  169.          *  In the latter case we want to run through the whole loop again.
  170.          */
  171.         TRPRINT(TR_DISK|TR_DISKRW, TR_LEVEL_1, ("failed: check again"));
  172.         goto checkAll;
  173.     }
  174.     /* 
  175.      * If we get here, there's truly 
  176.      * nothing to read from disk  so now let's see if anything is
  177.      * waiting to write to the disk.
  178.      * We move to the ready queue the first process from *each*
  179.      * disk queue wait list.  
  180.      */
  181.     TRPRINT(TR_DISK|TR_DISKRW, TR_LEVEL_1, 
  182.         ("Checking To Qs, lastTo %d, lastFrom %d",lastToQChecked,
  183.             lastFromQChecked));
  184.  
  185.     last = lastToQChecked;
  186.  
  187.     for(j=last+1, lastToQChecked=j%NumVolumes; 
  188.         (threads_awaiting_q>0) && (j<=(last+NumVolumes)); 
  189.         lastToQChecked = (++j)%NumVolumes) {
  190.         TCB                    *tcb;
  191.  
  192.         volRec  = diskQueue(lastToQChecked)->volRec;
  193.  
  194.         if( (volRec->volflags & VOL_OPEN)==0 ) 
  195.             continue;
  196.  
  197.         TRPRINT(TR_DISK|TR_DISKRW, TR_LEVEL_1, ("checking To Q disk %d",
  198.             lastToQChecked));
  199.  
  200. #define diskTakingRequests     tcbList
  201.         if(LIST_EMPTY( &(volRec->diskTakingRequests))) {
  202.             /* 
  203.              * noone waiting on this disk
  204.              */
  205.             continue;
  206.         }
  207.  
  208.         qp = diskQueue(lastToQChecked);
  209.         SM_ASSERT(LEVEL_3, qp);
  210.  
  211.         /* 
  212.          * we mustn't block here, so we only try once for the turn 
  213.          */
  214.         if(!tryMutex(&(qp->toDisk.mutex))) {
  215.             /* couldn't inspect queue -- skip to next volume */
  216.             continue;
  217.         }
  218.         if(toDiskFull(qp)) {
  219.             /* try next volume */
  220.             giveMutex(&(qp->toDisk.mutex));
  221.             continue;
  222.         }
  223.         giveMutex(&(qp->toDisk.mutex));
  224.         found++;
  225.         tcb = (TCB *) listDeq( &(volRec->diskTakingRequests) );
  226.         threads_awaiting_q--;
  227.         SM_ASSERT(LEVEL_1, tcb != NULL);
  228.  
  229.         CHECK_TCB_MAGIC(tcb);
  230.  
  231.         /*
  232.          *    check to see that the thread is in wait
  233.          *  with state == "waiting for disk q to shrink"
  234.          */
  235.         SM_ASSERT(LEVEL_3, tcb->state == THREAD_DISK_Q_WAIT);
  236.  
  237.         /*
  238.          *    put the thread on the ready queue
  239.          */
  240.         TRPRINT(TR_DISK, TR_LEVEL_1, 
  241.                 ("putting tcb %d on ready list", (tcb-Tcbs)));
  242.         listEnq( &ReadyList, &(tcb->controlList) );
  243.  
  244.         TRPRINT(TR_DISK, TR_LEVEL_3, ("process moved", lastToQChecked));
  245.  
  246.     }
  247.  
  248.     TRPRINT(TR_DISK, TR_LEVEL_1, 
  249.         ("select disk found %s", found?"something":"nothing"));
  250.     return found;
  251. }
  252.